﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;

namespace Kokomo.PeInspector.Test
{
	class _TestClass
	{

		class NestedGeneric<T>
		{
			class NestedNestedGeneric<T>
			{
			}
		}

		public static void TestPreIncrement()
		{
			int num = 0;
			Console.WriteLine(num);
			++num;
			Console.WriteLine(num);
		}

		public static void TestAnonymousDelegate()
		{
			Func<object, bool> isString = (obj) => (obj is string);

			Console.WriteLine(isString("hello"));
		}

		private void _TestLinqWhere()
		{
			IQueryable<object> queryable = null;

			var query =
				from r in queryable
				where (r is string)
				select r;

			Console.WriteLine(queryable);
		}

		private void _TestLinqQueryGroup()
		{
			IQueryable<Type> queryable = null;

			var q =
				from t in queryable
				from m in t.GetMembers()
				group m by m.MemberType into mg
				orderby mg.Key
				select new { Group = mg, Count = mg.Count() }
					;

			Console.WriteLine(queryable);
		}
		private void _TestNestedLinqQuery()
		{
			IQueryable<object> queryable = null;

			var query =
				from r in
					(
						from s in queryable
						where s.GetHashCode() != 0
						select s
						)
				where (r is string)
				select r.ToString();

			Console.WriteLine(queryable);
		}
		private void _TestLinqWhereProjected()
		{
			IQueryable<object> queryable = null;

			var query =
				from r in queryable
				where (r is string)
				select r.ToString();

			Console.WriteLine(queryable);
		}
		private void _TestLinqSelectMany()
		{
			IQueryable<Type> queryable = null;

			var query =
				from t in queryable
				from m in t.GetMembers()
				select m;

			Console.WriteLine(queryable);
		}
		private void _TestLinqSelectManyProjected()
		{
			IQueryable<Type> queryable = null;

			var query =
				from t in queryable
				from m in t.GetMembers()
				select m.ToString();

			Console.WriteLine(queryable);
		}
		private void _TestLinqSelectManyProjected2()
		{
			IQueryable<Type> queryable = null;

			var query =
				from t in queryable
				from m in t.GetMembers()
				select t;

			Console.WriteLine(queryable);
		}
		private void _TestLinqOrderBy()
		{
			IQueryable<Type> queryable = null;

			var query =
				from t in queryable
				orderby t.Name
				select t
				;

			Console.WriteLine(queryable);
		}

		private void _TestLinqQueryToObjects()
		{
			Type[] array = new Type[0];

			var q = from t in array
					from m in t.GetMembers()
					where m.MemberType == System.Reflection.MemberTypes.Method
					select m.Name;
		}
		private void _TestLinqQueryQuery()
		{
			IQueryable<Type> array = new Type[0].AsQueryable();

			var q = from t in array
					from m in t.GetMembers()
					where m.MemberType == System.Reflection.MemberTypes.Method
					select m.Name;
		}
		private void _TestDefaultParameterValue(int defaultParam = 1)
		{
		}
		private void _TestDynamic()
		{
			dynamic obj = new object();

			int hash = obj.GetHashCode();
		}
		private void _TestLambda()
		{
			Expression<Func<string, int>> stringLengthExpression = str => str.Length;
			string[] stringArray = new string[] { "String1", "String2", "String3" };
		}

		private TNew _TestGenericNewConstraint<TNew>() where TNew : new()
		{
			return new TNew();
		}
		private TNew _TestGenericStructConstraint<TNew>() where TNew : struct
		{
			return new TNew();
		}
		private TNew _TestGenericClassConstraint<TNew>() where TNew : class,new()
		{
			return new TNew();
		}
		private TNew _TestGenericTypeConstraint<TNew>() where TNew : Exception
		{
			return default(TNew);
		}
		private TBase _TestGenericNakedConstraint<TNew, TBase>(TNew value) where TNew : TBase
		{
			return value;
		}

		private int _TestIfReturn()
		{
			int i = 5;

			while (i < 5)
			{
				if (i > 0)
				{
					return i;
				}
			}

			return i;
		}
		private void _TestShortCircuitAnd()
		{
			int a = 10;
			int b = 20;

			if ((a < 10) && (b < 20))
			{
				Console.WriteLine("Both conditions match");
			}
		}

		private void _TestShortCircuitOr()
		{
			int a = 10;
			int b = 20;

			if ((a < 10) || (b < 20))
			{
				Console.WriteLine("Both conditions match");
			}
		}

		private void _TestBinaryOperatorOverload()
		{
			_TestClass x = new _TestClass();
			_TestClass y = new _TestClass();

			int result = x + y;
		}
		//private void _TestUnaryOperatorOverload()
		//{
		//    _TestClass x = new _TestClass();
		//    _TestClass y=x++;
		//}
		private void _TestImplicitOperator()
		{
			int x = new _TestClass();
		}
		private void _TestExplicitOperator()
		{
			int x = (short)(new _TestClass());
		}

		private void _TestForEachLoop()
		{
			int[] intArray = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
			IEnumerable<int> enumerable = intArray;
			foreach (var i in enumerable)
			{
				Console.WriteLine(i);
			}
		}

		private void _TestTryCatchAny()
		{
			int i = 1;

			try
			{
				System.Console.WriteLine("Test try-catch block");
			}
			catch
			{
				Console.WriteLine("Unspecified exception");
			}
		}

		private void _TestTryDoLoop()
		{
			int i = 0;
			try
			{
				do
				{
					i++;
					Console.WriteLine("The DO loop is nested in the try block");
				} while (i < 10);
			}
			catch
			{
				Console.WriteLine("Exception");
			}
		}

		private void _TestDoTryLoop()
		{
			int i = 0;
			do
			{
				try
				{
					Console.WriteLine("The TRY block is nested in the do loop");
				}
				catch
				{
					Console.WriteLine("Exception");
				}
				i++;
			} while (i < 10);
		}

		private void _TestTryCatchINvalidOperationException()
		{
			int i = 1;
			try
			{
				Console.WriteLine("Test try-catch block");
			}
			catch (InvalidOperationException ex)
			{
				Console.WriteLine("InvalidOperationException");
			}
		}

		private void _TestTryFinallyBlock()
		{
			int i = 1;

			try
			{
				Console.WriteLine("Test try-catch block");
			}
			finally
			{
				Console.WriteLine("Finally");
			}
		}

		private void _TestSwitchWithoutDefault()
		{
			int i = 5;
			i++;

			switch (i)
			{
				case 0:
					i = 0;
					break;
				case 1:
				case 2:
					i = 2;
					i += 3;
					break;
			}
			System.Console.WriteLine(i);
		}
		private void _TestSwitchWithDefault()
		{
			int i = 5;
			i++;

			switch (i)
			{
				default:
					i = -1;
					break;
				case 0:
					i = 0;
					break;
				case 1:
				case 2:
					i = 2;
					i += 3;
					break;
			}
			System.Console.WriteLine(i);
		}
		private void _TestSwitchWithEnum()
		{
			int i = 5;
			i++;

			MemberTypes memberType = MemberTypes.Field;
			string text = null;
			switch (memberType)
			{
				case MemberTypes.All:
					break;
				case MemberTypes.Constructor:
					text = "Constructor";
					break;
				case MemberTypes.Custom:
					text = "Custom";
					break;
				case MemberTypes.Event:
					text = "Event";
					break;
				case MemberTypes.Field:
					text = "Field";
					break;
				case MemberTypes.Method:
					text = "Method";
					break;
				case MemberTypes.NestedType:
				case MemberTypes.Property:
				case MemberTypes.TypeInfo:
				default:
					text = "NestedType, Property, TypeInfo, or something else";
					break;
			}

			System.Console.WriteLine(i);
		}
		private void _TestConditionalExpression()
		{
			int i = 5;
			int conditional = (i == 5) ? 3 : 1;
			Console.WriteLine(conditional);
			Console.WriteLine(conditional);
		}
		private void _TestIfBlock()
		{
			DateTime now = DateTime.Now;

			if (now.Millisecond < 100)
			{
				Console.Write("Before 100");
			}
			else
			{
				Console.Write("After 100");
			}
		}
		private void _TestIfBlockNested()
		{
			DateTime now = DateTime.Now;

			if (now.Millisecond < 100)
			{
				Console.Write("Before 100");
				if (now.Millisecond < 50)
				{
					Console.Write("Before 50");
				}
				else
				{
					Console.Write("After 50");
				}
			}
			else
			{
				Console.Write("After 100");
				if (now.Millisecond < 150)
				{
					Console.Write("Before 150");
				}
				else
				{
					Console.Write("After 150");
				}
			}
		}
		private void _TestWhileLoop()
		{
			int num = 0;
			while (num < 10)
			{
				num++;
			}
		}
		private void _TestDoLoop()
		{
			int num = 0;
			do
			{
				num++;
			} while (num < 10);
		}
		private void _TestNestedDoLoop()
		{
			int num1 = 0;
			int num2 = 0;

			while (num1 < 10)
			{
				do
				{
					num2++;
				} while (num2 < 10);
			}
		}
		private void _TestImplicitArray()
		{
			List<string> list = new List<string>();
			list.AddRange(new string[] { "String1", "String2", "String3" });

			string[] newStringArray;
			list.AddRange(newStringArray = new string[] { "String1", "String2", "String3" });
			Console.WriteLine(newStringArray);
		}
		private void _TestObjectMemberInitializers()
		{
			//List<object> list = new List<object>() { new TextStyle() { FontFamily = new FontFamily("Courier New"), EmSize = 14 } };
		}
		private void _TestChainedIfBlocks()
		{
			int i = 5;

			if (i < 1)
			{
				Console.WriteLine("i < 1");
			}
			else if (i < 2)
			{
				Console.WriteLine("i < 2");
			}
			else if (i < 3)
			{
				Console.WriteLine("i < 3");
			}
			else
			{
				Console.WriteLine("I could be anything");
			}
		}
	}
}
